/**
 * 增强型表文档生成器
 * 
 * 提供高级的文档生成功能，支持多种模板引擎和自定义格式
 * 
 * @module enhancedTableDocsGenerator
 */

const fs = require('fs');
const path = require('path');
// 这里需要安装这些依赖
// const ejs = require('ejs');
// const handlebars = require('handlebars');
// const marked = require('marked');
// const prismjs = require('prismjs');

// 默认配置
const DEFAULT_CONFIG = {
    templatesDir: path.join(__dirname, '../templates'),
    fallbackTemplatesDir: path.join(__dirname, '../templates/fallback'),
    outputDir: path.join(__dirname, '../tables'),
    typesDir: path.join(__dirname, '../types'),
    templateEngine: 'handlebars',
    defaultDocFormat: 'markdown',
    defaultTemplateFile: 'table-document-template.md',
    defaultTsTemplateFile: 'typescript-interface-template.ts',
    highlightCode: true,
    includeApiExamples: true,
    includeFieldExamples: true,
    includeRelationDiagrams: false
};

// 加载和注册模板
const loadedTemplates = new Map();
const templateEngines = {
    handlebars: {
        compile: (templateSource) => {
            // 这里需要安装handlebars依赖
            console.log('编译Handlebars模板');
            // 返回一个简单的模板函数用于演示
            return (data) => {
                return templateSource.replace(/\[\[([^\]]+)\]\]/g, (match, key) => {
                    const value = key.split('.').reduce((obj, k) => obj && obj[k], data);
                    return value !== undefined ? value : match;
                });
            };
        },
        render: (template, data) => template(data)
    },
    ejs: {
        compile: (templateSource) => {
            // 这里需要安装ejs依赖
            console.log('编译EJS模板');
            // 返回一个简单的模板函数用于演示
            return (data) => {
                return templateSource.replace(/<%= ([^%]+) %>/g, (match, key) => {
                    const value = key.split('.').reduce((obj, k) => obj && obj[k], data);
                    return value !== undefined ? value : match;
                });
            };
        },
        render: (template, data) => template(data)
    }
};

/**
 * 注册自定义Handlebars助手函数
 */
function registerHandlebarsHelpers() {
    console.log('注册Handlebars助手函数');
    // 实际实现需要安装handlebars依赖
}

/**
 * 加载模板文件
 * 
 * @param {string} templateName - 模板名称
 * @param {string} templateEngine - 模板引擎
 * @param {Object} options - 选项
 * @returns {Function} 编译后的模板函数
 */
function loadTemplate(templateName, templateEngine = 'handlebars', options = {}) {
    const { templatesDir, fallbackTemplatesDir } = { ...DEFAULT_CONFIG, ...options };

    // 检查是否已加载
    const cacheKey = `${templateEngine}:${templateName}`;
    if (loadedTemplates.has(cacheKey)) {
        return loadedTemplates.get(cacheKey);
    }

    // 查找模板文件
    let templatePath = path.join(templatesDir, templateName);
    if (!fs.existsSync(templatePath) && fallbackTemplatesDir) {
        templatePath = path.join(fallbackTemplatesDir, templateName);
    }

    if (!fs.existsSync(templatePath)) {
        throw new Error(`找不到模板文件: ${templateName}`);
    }

    // 读取模板内容
    const templateSource = fs.readFileSync(templatePath, 'utf8');

    // 获取模板引擎
    const engine = templateEngines[templateEngine];
    if (!engine) {
        throw new Error(`不支持的模板引擎: ${templateEngine}`);
    }

    // 编译模板
    const template = engine.compile(templateSource);

    // 缓存模板
    loadedTemplates.set(cacheKey, template);

    return template;
}

/**
 * 生成表文档
 * 
 * @param {Object} tableData - 表数据
 * @param {Object} options - 选项
 * @returns {string} 生成的文档内容
 */
function generateTableDoc(tableData, options = {}) {
    const config = { ...DEFAULT_CONFIG, ...options };
    const { templateEngine, defaultTemplateFile } = config;

    // 加载模板
    const template = loadTemplate(defaultTemplateFile, templateEngine, config);

    // 准备模板数据
    const templateData = {
        table: tableData,
        meta: {
            generatedAt: new Date(),
            version: process.env.npm_package_version || '1.0.0'
        },
        options: config
    };

    // 渲染模板
    return templateEngines[templateEngine].render(template, templateData);
}

/**
 * 生成TypeScript接口定义
 * 
 * @param {Object} tableData - 表数据
 * @param {Object} options - 选项
 * @returns {string} 生成的TypeScript接口内容
 */
function generateTypeDefinition(tableData, options = {}) {
    const config = { ...DEFAULT_CONFIG, ...options };
    const { templateEngine, defaultTsTemplateFile } = config;

    // 准备类型数据
    const typeData = prepareTypeData(tableData);

    // 加载模板
    try {
        const template = loadTemplate(defaultTsTemplateFile, templateEngine, config);
        return templateEngines[templateEngine].render(template, typeData);
    } catch (error) {
        // 如果模板不存在，使用内联模板
        console.warn(`TypeScript模板加载失败: ${error.message}，使用内联模板`);
        return generateInlineTypeDefinition(typeData);
    }
}

/**
 * 准备TypeScript类型数据
 * 
 * @param {Object} tableData - 表数据
 * @returns {Object} 处理后的类型数据
 */
function prepareTypeData(tableData) {
    const { tableName, tableComment, columns } = tableData;

    // 获取接口名称
    const interfaceName = getInterfaceNameFromTableName(tableName);

    // 处理列类型
    const typeFields = columns.map(col => {
        return {
            name: col.columnName,
            tsType: mapDbTypeToTsType(col.dataType, col),
            description: col.columnComment || `${col.columnName}字段`,
            isRequired: col.isNullable === 'NO',
            isPrimaryKey: col.isPrimaryKey === 'YES',
            defaultValue: col.defaultValue
        };
    });

    return {
        interfaceName,
        tableName,
        tableComment: tableComment || `${tableName}表`,
        fields: typeFields,
        generatedAt: new Date().toISOString()
    };
}

/**
 * 将数据库类型映射到TypeScript类型
 * 
 * @param {string} dbType - 数据库字段类型
 * @param {Object} column - 列信息对象
 * @returns {string} TypeScript类型
 */
function mapDbTypeToTsType(dbType, column) {
    // 处理NULL
    const nullable = column.isNullable === 'YES' ? ' | null' : '';

    // 根据数据库类型映射
    const type = dbType.toLowerCase();

    if (type.includes('int')) {
        // 大整数使用字符串表示
        if (type.includes('bigint') && column.numericPrecision > 15) {
            return `string${nullable}`;
        }
        return `number${nullable}`;
    }

    if (type.includes('float') || type.includes('double') || type.includes('decimal') || type.includes('numeric')) {
        return `number${nullable}`;
    }

    if (type.includes('bool') || type.includes('bit')) {
        return `boolean${nullable}`;
    }

    if (type.includes('date') || type.includes('time')) {
        return `string${nullable}`;
    }

    // 枚举类型处理
    if (type.includes('enum')) {
        const enumValues = column.column_type?.match(/'([^']*)'/g)
            ?.map(v => v.replace(/'/g, ''))
            ?.map(v => `'${v}'`)
            ?.join(' | ') || 'string';
        return `${enumValues}${nullable}`;
    }

    // 默认为字符串
    return `string${nullable}`;
}

/**
 * 从表名生成接口名称
 * 
 * @param {string} tableName - 表名
 * @returns {string} 接口名称
 */
function getInterfaceNameFromTableName(tableName) {
    // 移除特殊前缀
    const cleanName = tableName.replace(/^(tbl_|dt_|sys_|jy_|at_)/, '');

    // 将下划线分隔的名称转为驼峰命名
    const pascalCase = cleanName
        .split('_')
        .map(part => part.charAt(0).toUpperCase() + part.slice(1))
        .join('');

    return `I${pascalCase}`;
}

/**
 * 内联生成TypeScript接口定义（当模板不可用时）
 * 
 * @param {Object} typeData - 类型数据
 * @returns {string} 生成的TypeScript代码
 */
function generateInlineTypeDefinition(typeData) {
    const { interfaceName, tableName, tableComment, fields } = typeData;

    let code = `/**\n`;
    code += ` * ${tableComment}\n`;
    code += ` * 表名：${tableName}\n`;
    code += ` * @autoGenerated\n`;
    code += ` */\n`;
    code += `export interface ${interfaceName} {\n`;

    // 生成字段
    fields.forEach(field => {
        code += `  /**\n`;
        code += `   * ${field.description}\n`;
        if (field.isPrimaryKey) {
            code += `   * @primaryKey\n`;
        }
        code += `   */\n`;
        code += `  ${field.name}${field.isRequired ? '' : '?'}: ${field.tsType};\n\n`;
    });

    code += `}\n`;

    return code;
}

/**
 * 保存生成的文档到文件
 * 
 * @param {string} content - 文档内容
 * @param {string} outputPath - 输出路径
 * @returns {boolean} 是否保存成功
 */
function saveDocToFile(content, outputPath) {
    try {
        // 确保目录存在
        const dir = path.dirname(outputPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
        }

        fs.writeFileSync(outputPath, content, 'utf8');
        console.log(`文档已保存到: ${outputPath}`);
        return true;
    } catch (error) {
        console.error(`保存文档失败: ${error.message}`);
        return false;
    }
}

/**
 * 批量生成多个表的文档
 * 
 * @param {Array<Object>} tablesData - 表数据数组
 * @param {Object} options - 选项
 * @returns {Object} 处理结果统计
 */
function generateMultipleTableDocs(tablesData, options = {}) {
    const config = { ...DEFAULT_CONFIG, ...options };
    const { outputDir, typesDir } = config;

    // 统计
    const stats = {
        total: tablesData.length,
        docsSuccess: 0,
        docsFailed: 0,
        typesSuccess: 0,
        typesFailed: 0,
        skipped: 0,
        errors: []
    };

    // 注册Handlebars助手
    if (config.templateEngine === 'handlebars') {
        registerHandlebarsHelpers();
    }

    // 处理每个表
    tablesData.forEach(tableData => {
        try {
            const { tableName } = tableData;

            // 检查是否需要跳过
            if (tableData.skip) {
                stats.skipped++;
                console.log(`跳过表: ${tableName}`);
                return;
            }

            // 生成文档
            const docContent = generateTableDoc(tableData, config);
            const docPath = path.join(outputDir, `${tableName}.md`);
            if (saveDocToFile(docContent, docPath)) {
                stats.docsSuccess++;
            } else {
                stats.docsFailed++;
                stats.errors.push(`保存${tableName}文档失败`);
            }

            // 生成类型定义
            const typeContent = generateTypeDefinition(tableData, config);
            const typePath = path.join(typesDir, `${tableName}.ts`);
            if (saveDocToFile(typeContent, typePath)) {
                stats.typesSuccess++;
            } else {
                stats.typesFailed++;
                stats.errors.push(`保存${tableName}类型定义失败`);
            }
        } catch (error) {
            console.error(`处理表${tableData.tableName}时出错:`, error);
            stats.docsFailed++;
            stats.typesFailed++;
            stats.errors.push(`处理${tableData.tableName}失败: ${error.message}`);
        }
    });

    return stats;
}

// 导出模块
module.exports = {
    generateTableDoc,
    generateTypeDefinition,
    generateMultipleTableDocs,
    mapDbTypeToTsType,
    getInterfaceNameFromTableName,
    loadTemplate,
    saveDocToFile
}; 